<template>
  <div class="erp-page-advanced-query">
    <el-form
      class="erp-list__form"
      :model="form"
      :rules="rules"
      :label-width="formLabelWidth"
      :inline="false"
      :label-suffix="labelSuffix"
    >
      <div
        v-for="(group, groupIndex) in groupForm"
        :key="groupIndex"
        class="form-group erp-page-form-body"
      >
        <div
          v-for="(box, boxIndex) in group.items"
          :key="boxIndex"
          class="form-box"
          :class="{hasHeader: box.title}"
        >
          <div
            v-if="box.title"
            class="form-box-header"
          >
            <span class="form-box-header-icon">·</span> {{ box.title }}
          </div>
          <el-row
            v-if="box.items && box.items.length > 0"
            v-show="box.visible === undefined || box.visible"
          >
            <div
              v-for="(item, index) in box.items"
              v-if="hiddenFormItem(item)"
              :key="index"
            >
              <erp-list-page
                v-if="item.viewType === 'list'"
                :options.sync="item.options"
                :extra-data="form"
                @change-options="changeOptions($event, item)"
              />
              <div
                v-else-if="item.viewType !== undefined"
              >
                <!--        头部换行-->
                <el-col
                  v-if="lineFeed(item) === 'head'"
                  :span="24"
                />
                <!--        独占一行-->
                <el-col
                  v-if="lineFeed(item) === 'all'"
                  :span="24"
                />
                <erp-form-col
                  :label="item.title"
                  :prop="item.field"
                  :label-width="labelWidth(item)"
                  :block="block(item)"
                >
                  <erp-view-item
                    :type="item.viewType"
                    :prop="item.field"
                    :value="form[item.field]"
                    :template="item.template"
                    :row-data="form"
                    :extra="item.extra"
                  />
                </erp-form-col>
                <el-col
                  v-if="lineFeed(item) === 'all'"
                  :span="24"
                />
                <!--        尾部换行-->
                <el-col
                  v-if="lineFeed(item) === 'foot'"
                  :span="24"
                />
              </div>
              <erp-form-item
                v-else
                :item="item"
                :value="form[item.field]"
                :form="form"
                @update-field="handleUpdateField"
                @value-change="handleValueChange"
              />
            </div>
            <erp-col>
              <div style="margin-left: 20px; margin-bottom: 15px;">
                <el-button
                  type="primary"
                  :disabled="advancedQueryLoading"
                  @click="submitSearch"
                >
                  {{ $t('common.search') }}
                </el-button>
                <el-button
                  :disabled="advancedQueryLoading"
                  @click="resetSearch"
                >
                  {{ $t('common.reset') }}
                </el-button>
              </div>
            </erp-col>
          </el-row>
        </div>
      </div>
    </el-form>
    <div class="footer">
      <!--            <el-button @click="submitSearch" type="primary">{{$t('common.search')}}</el-button>-->
      <!--            <el-button @click="resetSearch">{{$t('common.reset')}}</el-button>-->
    </div>
  </div>
</template>

<script>
import Vue from 'vue';
import {generateGroupForm, cloneJson} from "@/utils";
import ErpFormCol from "@/components/erp/ErpPageForm/ErpFormCol";
import ErpCol from "@/components/erp/ErpPageForm/ErpCol";
import ErpFormItem from '@/components/erp/ErpListForm/ErpFormItem';
import {Form} from "element-ui";
import {base as request} from '@/request';
import {generateNewForm, getServerDataSource} from "../../../utils/form";

Vue.use(Form);
const ErpListPage = () => import('@/components/erp/ErpListPage/ErpListPage');
const ErpViewItem = () => import('@/components/erp/ErpListView/ErpViewItem');
/**
 * 高级查询框
 * @author maolin
 */
export default {
  name: "ErpPageAdvancedQuery",
  components: {
    ErpFormCol,
    ErpCol,
    ErpFormItem,
    ErpListPage,
    ErpViewItem
  },
  props: {
    /**
     * 是否加载中
     * @public
     */
    advancedQueryLoading: {
      type: Boolean,
      default: false
    },
    /**
     * 高级查询表单配置项列表
     * @public
     */
    formConfigList: {
      type: Array,
      default () {
        return [];
      }
    },
    /**
     * 有额外的树搜索时，在搜索时需要带上树的key
     * @public
     */
    treeSearchKey: {
      type: String,
      default: ''
    },
    /**
     * 表单项标题后缀
     * @public
     */
    labelSuffix: {
      type: String,
      default: '：'
    },
    /**
     * 表单项标题宽度
     * @public
     */
    formLabelWidth: {
      type: String,
      default() {
        return '100px';
      }
    },
    /**
     * 数据源配置
     * @public
     */
    dataSourceApi: {
      type: [Object, String],
      default: ''
    },
    /**
     * 额外参数
     * @public
     */
    query: {
      type: Object,
      default: () => {}
    }
  },
  data () {
    return {
      configList: [],
      form: {},
      initFormObj: {}
    };
  },
  computed: {
    groupForm () {
      if (this.configList) {
        return generateGroupForm(cloneJson(this.configList));
      }
      return [];
    },
    hiddenFormItem () {
      return function (item) {
        if (item.visibleFunction) {
          try{
            return new Function('form','field', 'query', item.visibleFunction )(this.form, item.field, this.query);
          }catch(e) {
            console.log('visibleFunction error');
            console.log(e);
          }
        }
        return true;
      };
    },
    block () {
      return function (item) {
        let times = item === undefined || item.col === undefined ? null : item.col.times;
        if(!times || isNaN(times) || times <= 0) {
          times = 1;
        }
        return times;
      };
    },
    labelWidth () {
      return function (item) {
        return item === undefined || item.col === undefined ? null : item.col.labelWidth;
      };
    },
    lineFeed () {
      return function (item) {
        let lineFeed = item === undefined || item.col === undefined ? null : item.col.lineFeed;
        if (lineFeed !== 'head' && lineFeed !== 'foot' && lineFeed !== 'all') {
          lineFeed = null;
        }
        return lineFeed;
      };
    },
    rules () {
      let rules = {};
      let formList = cloneJson(this.formConfigList);
      if (formList && formList.length > 0) {
        for (let i in formList) {
          if (formList[i].validate && formList[i].validate.length > 0) {
            let validateArray = formList[i].validate;
            if (validateArray && validateArray.length > 0) {
              for (let j in validateArray) {
                if (validateArray[j].pattern !== undefined) {
                  validateArray[j].pattern = eval(validateArray[j].pattern);
                }
              }
            }
            rules[formList[i].field] = formList[i].validate;
          }
        }
      }
      return rules;
    },
    dataSourceApiUrl () {
      if (typeof this.dataSourceApi === 'string') {
        return this.dataSourceApi;
      } else if (typeof this.dataSourceApi === 'object') {
        return this.dataSourceApi.url;
      }
      return '';
    }
  },
  mounted() {
    this.initForm();
  },
  methods: {
    /**
     * 初始化表单
     * @private
     * @returns {Promise<void>}
     */
    async initForm () {
      let formConfigList = cloneJson(this.formConfigList);
      formConfigList = await this.getServerDataSource(formConfigList);
      this.configList = formConfigList;
      let initForm = this.generateNewForm(formConfigList);
      this.form = cloneJson(initForm);
      this.initFormObj = cloneJson(this.form);
    },
    /**
     * 获取高级查询表单数据源
     * @private
     * @param formList
     * @returns {Promise<unknown>}
     */
    getServerDataSource (formList) {
      return new Promise( (resolve, reject) => {
        getServerDataSource(formList, this.dataSourceApi, this.query, this.preViewFunction, this.treeSearchKey)
          .then((res) => {
            if (res.treeSearchData) {
              this.$emit('get-tree-search-data', res.treeSearchData);
            }
            resolve(res.formList);
            return res.formList;
          })
          .catch(err => {
            console.log(err);
            reject(err);
          });
      });
    },
    /**
     * 通过表单配置生成表单对象
     * @private
     * @param formList
     * @returns {{}}
     */
    generateNewForm (formList) {
      return generateNewForm(formList, this.query, this.form);
    },
    /**
     * 判断表单项是否可见
     * @private
     * @param item
     * @param query
     * @returns {boolean|*}
     */
    visibleFunc (item, query) {
      if (item.visibleFunction) {
        let form = this.form;
        let field = item.field;
        try{
          return new Function('form','field', 'query', item.visibleFunction )(form, field, query);
        }catch(e) {
          return true;
        }
      }
      return true;
    },
    /**
     * 更新表格配置
     * @private
     * @param options
     * @param item
     */
    changeOptions (options, item) {
      let formList = this.formConfigList;
      if (formList && formList.length > 0) {
        for (let i in formList) {
          if (formList[i].field === item.field) {
            formList[i].options = options;
          }
        }
      }
    },
    /**
     * 更新表单其他值
     * @private
     * @param {object} fieldObj 值对象{field1：value1,field2：value2}
     */
    handleUpdateField (fieldObj) {
      let form = this.form;
      if (form) {
        for (let i in form) {
          if (fieldObj[i] !== undefined) {
            form[i] = fieldObj[i];
          }
        }
      }
    },
    /**
     * 更新表单值
     * @private
     * @param {object} obj 值对象{field,value}
     */
    handleValueChange (obj) {
      let form = this.form;
      if (obj.field) {
        form[obj.field] = obj.value;
      }
    },
    /**
     * 提交搜索
     * @public
     */
    submitSearch () {
      this.$emit('search', cloneJson(this.form));
    },
    /**
     * 重置搜索
     * @public
     */
    resetSearch () {
      this.form = cloneJson(this.initFormObj);
      this.$emit('search', cloneJson(this.form));
    }
  }
};
</script>

<style lang="scss" scoped>
    $primaryColor: var(--primary-color);
    $fontSize: var(--font-size);
    .erp-page-advanced-query{
        padding: 15px;
        padding-bottom: 0;
        .footer{
            text-align: center;
        }
        .form-group{
            margin-bottom: 20px;
            &:last-child{
                margin-bottom: 0;
            }
            .form-box{
                margin-bottom: 20px;
                &:last-child{
                    margin-bottom: 0;
                }
                .form-box-header{
                    color: #092C4C;
                    margin-bottom: 10px;
                    font-size: $fontSize;
                    font-weight: bold;
                    margin-left: 10px;
                    .form-box-header-icon{
                        font-size: 30px;
                        line-height: $fontSize;
                        float: left;
                        color: $primaryColor;
                    }
                }
            }
        }
    }

</style>
